import cv2 as cv
import numpy as np

# 阈值分割大津阈值算法
'''
cv2.threshold()用来实现阈值分割，ret是return value缩写，代表当前的阈值，暂时不用理会。函数有4个参数：
参数1：要处理的原图，一般是灰度图 
参数2：设定的阈值
参数3：最大阈值，一般为255
参数4：阈值的方式，主要有8种，详情：ThresholdTypes
THRESH_BINARY 
THRESH_BINARY_INV
THRESH_TRUNC 
THRESH_TOZERO 
THRESH_TOZERO_INV
THRESH_MASK 
THRESH_OTSU大津阈值算法
THRESH_TRIANGLE 
'''
def otsu_demo(image):
    ret, th = cv.threshold(image, 127, 255, cv.THRESH_OTSU)
    cv.imshow('THRESH_OTSU', th)


'''
种子填充
cv2.floodFill(img,mask,seed,newvalue(BGR),(loDiff1,loDiff2,loDiff3),(upDiff1,upDiff2,upDiff3),flag)
    img：为待使用泛洪算法的图像
	mask：为掩码层，使用掩码可以规定是在哪个区域使用该算法，如果是对于完整图像都要使用，则掩码层大小为原图行数+2，列数+2.是一个二维的0矩阵，边缘一圈会在使用算法是置为1。而只有对于掩码层上对应为0的位置才能泛洪，所以掩码层初始化为0矩阵。【dtype:np.uint8】
	seed：为泛洪算法的种子点，也是根据该点的像素判断决定和其相近颜色的像素点，是否被泛洪处理。
    newvalue：是对于泛洪区域新赋的值（B,G,R）
	(loDiff1,loDiff2,loDiff3)：是相对于seed种子点像素可以往下的像素值，即seed(B0,G0,R0)，泛洪区域下界为（B0-loDiff1,G0-loDiff2,R0-loDiff3）
	(upDiff1,upDiff2,upDiff3)：是相对于seed种子点像素可以往上的像素值，即seed(B0,G0,R0)，泛洪区域上界为（B0+upDiff1,G0+upDiff2,R0+upDiff3）
	flag：为泛洪算法的处理模式。
'''
def fill_color_demo(image):
    copyIma = image.copy()
    h, w = image.shape[:2]
    print(h, w)
    # mask必须行和列都加2，且必须为uint8单通道阵列
    # 为什么要加2可以这么理解：当从0行0列开始泛洪填充扫描时，mask多出来的2可以保证扫描的边界上的像素都会被处理
    mask = np.zeros([h+2, w+2], np.uint8)
    cv.floodFill(copyIma, mask, (30, 30), (255, 255, 0), (100, 100, 100), (50, 50, 50), cv.FLOODFILL_FIXED_RANGE)
    cv.imshow("fill_color", copyIma)


# 灰度图读入
src = cv.imread("./rice.png", 0)
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
otsu_demo(src)
fill_color_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

